home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / µSim 1.1 / source / Dump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-25  |  13.2 KB  |  536 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993-1997 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11. #include    <Limits.h>
  12.  
  13. #include    "UtilsSys7.h"
  14. #include    "Conversions.h"
  15. #include    "FabWList.h"
  16. #include    "Independents.h"
  17. #include    "SimResIDs.h"
  18.  
  19. #include    "Globals.h"
  20. #include    "Disasm.h"
  21. #include    "Dump.h"
  22. #include    "DoEditDialog.h"
  23. #include    "DoMenu.h"
  24. #include    "Main.h"
  25. #include    "Input.h"
  26. #include    "Registers.h"
  27. #include    "Scroll.h"
  28. #include    "TrackThumb.h"
  29. #include    "DragManSim.h"
  30. #include    "SimUtils.h"
  31.  
  32.  
  33. #if defined(FabSystem7orlater)
  34.  
  35.  
  36. static ControlRef    dumpVScroll;
  37. static WindowRef    curPosW;
  38. static short    dumpLineHeight, dumpFromTop, dumpCWidMax;
  39.  
  40. static void NoRealTimeActionProc(ControlHandle control, short value);
  41. static void RealTimeActionProc(ControlHandle control, short value);
  42. static pascal void DumpActionProc(ControlHandle control, short part);
  43. static void DrawLine(Ptr start);
  44. static short TrackDumpObject(RectPtr r, short theLoc);
  45.  
  46. #pragma segment Init
  47.  
  48. /* InitDump: initializes the Dump window */
  49.  
  50. OSErr InitDump(void)
  51. {
  52. enum {
  53. kCharsInOneLine = 0x002D0000
  54. };
  55.  
  56. FMetricRec    theMetrics;
  57. FabWindowPtr    thefabw;
  58. Fixed    tempFix;
  59. WindowPtr    window;
  60. OSErr    err = appMemFullErr;
  61.  
  62. gWPtr_Dump = window = GetNewWindow(kWIND_Dump, nil, (WindowPtr)-1L);
  63. if (window) {
  64.     SetPortWindowPort(window);
  65.     if (gPrefs.remembWind)
  66.         if (IsOnScreenWeak(gPrefs.DumpTopLeft))
  67.             MoveWindow(window, gPrefs.DumpTopLeft.h, gPrefs.DumpTopLeft.v, false);
  68.     if (dumpVScroll = GetNewControl(kCNTL_dmpVScroll, window)) {
  69.         TextFont(monaco);
  70.         TextSize(9);
  71.         TextMode(srcCopy);
  72.         FontMetrics(&theMetrics);
  73.         tempFix = theMetrics.descent + theMetrics.ascent + theMetrics.leading;
  74.         tempFix = mySwap(tempFix);
  75.         dumpLineHeight = (short)tempFix;
  76.         dumpFromTop = *(short *)&theMetrics.ascent;
  77.         dumpCWidMax = *(short *)&theMetrics.widMax;
  78.         tempFix = FixMul(theMetrics.widMax, kCharsInOneLine);
  79.         tempFix = mySwap(tempFix);
  80.         SizeWindow(window, (short)tempFix + kScrollbarWidth + kDIST_FROMLEFT,
  81.             gPrefs.remembWind ? gPrefs.DumpHeight :
  82.                 ((PRCT_B(window) - PRCT_T(window)) / dumpLineHeight) * dumpLineHeight,
  83.             false);
  84.         SetupVertScrollBar(window, dumpVScroll);
  85.         SetupDumpCtlMax(dumpVScroll);
  86.         if (gPrefs.remembWind)
  87.             SetControlValue(dumpVScroll, gPrefs.DumpScrollVal);
  88.  
  89.         thefabw = AddWindowToList(window);
  90.         SetActivate(thefabw, Activate_Dump);
  91.         SetUpdate(thefabw, Update_Dump);
  92.         SetGrow(thefabw, Grow_Dump);
  93.         SetGoAway(thefabw, CloseDump);
  94.         SetContent(thefabw, Do_Dump);
  95.         SetGetDragRect(thefabw, getDragRectDump);
  96.  
  97.         InstallRgnHandler(thefabw, NewRgn(), RecalcDump, nil,
  98.                 toMenu(kBalloons_Dump, kBDump_Contents), 0, 0);
  99.  
  100.         ResizeObjects(window);
  101.         RecalcGlobalCoords(thefabw);
  102.  
  103.         if (gDragManagerActive)
  104.             (void) MyInstallHWindow(window);
  105.         err = noErr;
  106.         }
  107.     }
  108. return err;
  109. } /* InitDump */
  110.  
  111.  
  112. #pragma segment Main
  113.  
  114. /*
  115. GetDumpVScrollValue: accessor */
  116.  
  117. short GetDumpVScrollValue(void)
  118. {
  119. return GetControlValue(dumpVScroll);
  120. }
  121.  
  122. /*
  123. GetDumpLineHeight: accessor */
  124.  
  125. short GetDumpLineHeight(void)
  126. {
  127. return dumpLineHeight;
  128. }
  129.  
  130. void ScrollDumpTo(short newPos)
  131. {
  132. SetControlValue(dumpVScroll, newPos);
  133. InvalDump();
  134. }
  135.  
  136. void DumpHome(void)
  137. {
  138. SetControlValue(dumpVScroll, GetControlMinimum(dumpVScroll));
  139. InvalDump();
  140. }
  141.  
  142. void DumpEnd(void)
  143. {
  144. SetControlValue(dumpVScroll, GetControlMaximum(dumpVScroll));
  145. InvalDump();
  146. }
  147.  
  148. void DumpPgUp(void)
  149. {
  150. DumpActionProc(dumpVScroll, kControlPageUpPart);
  151. }
  152.  
  153. void DumpPgDn(void)
  154. {
  155. DumpActionProc(dumpVScroll, kControlPageDownPart);
  156. }
  157.  
  158. void Activate_Dump(EventRecord */*evt*/, WindowPtr w, Handle, short, Boolean becomingActive)
  159. {
  160. Rect    growRect;
  161.  
  162. /* the growbox needs to be redrawn on activation: */
  163. growRect = w->portRect;
  164. /* adjust for the scrollbars */
  165. growRect.top = growRect.bottom - kScrollbarAdjust + 1;
  166. growRect.left = growRect.right - kScrollbarAdjust + 1;
  167. if (becomingActive) {
  168.     InvalRect(&growRect);    /* we cannot avoid grow box flicker */
  169.     if ((*dumpVScroll)->contrlVis == 0) {
  170.         ShowControl(dumpVScroll);
  171.         ValidRect(&(*dumpVScroll)->contrlRect);
  172.         }
  173.     }
  174. else {
  175. /* the control must be redrawn on deactivation: */
  176.     HideControl(dumpVScroll);
  177.     InvalRect(&growRect);
  178.     }
  179. } /*Activate*/
  180.  
  181. void Grow_Dump(WindowPtr w, EventRecord *event)
  182. {
  183. Rect    tempRect, updateRect;
  184. long    growResult;
  185.  
  186. tempRect.right = tempRect.left = PRCT_R(w) + 1;
  187. tempRect.bottom = SHRT_MAX;        /* set up limiting values */
  188. tempRect.top = kMinDocDim + 30;
  189. updateRect = w->portRect;
  190. updateRect.top = updateRect.bottom - kScrollbarAdjust;
  191. /* see if it really changed size */
  192. if (growResult = GrowWindow(w, event->where, &tempRect)) {
  193.     SizeWindow(w, LoWrd(growResult),
  194.                 (HiWrd(growResult) / dumpLineHeight) * dumpLineHeight, true);
  195.     SizeControl(dumpVScroll, kScrollbarWidth, PRCT_B(w) - PRCT_T(w) - 13);
  196.     if (HiWrd(growResult) > updateRect.bottom)
  197.         /* enlarged */
  198.         InvalRect(&updateRect);
  199.     else /* reduced */ {
  200.         updateRect.bottom = PRCT_B(w);
  201.         updateRect.right = PRCT_R(w);
  202.         updateRect.top = updateRect.bottom - kScrollbarAdjust + 1;
  203.         updateRect.left = updateRect.right - kScrollbarAdjust + 1;
  204.         InvalRect(&updateRect);
  205.         }
  206.     ValidRect(&(*dumpVScroll)->contrlRect);
  207.     SetupDumpCtlMax(dumpVScroll);
  208.     }
  209. }
  210.  
  211. void Update_Dump(WindowPtr w, short)
  212. {
  213. Rect    growRect;
  214. RgnHandle    oldClip;
  215.  
  216. if (EmptyRgn(w->visRgn) == false) {    /* draw if updating needs to be done */
  217.     DrawDump(w);
  218.     oldClip = NewRgn();
  219.     GetClip(oldClip);
  220.     growRect = w->portRect;
  221.     growRect.left = growRect.right - kScrollbarAdjust;
  222.     ClipRect(&growRect);
  223.     DrawGrowIcon(w);
  224.     SetClip(oldClip);
  225.     DisposeRgn(oldClip);
  226.     UpdateControls(w, w->visRgn);
  227.     }
  228. }
  229.  
  230. void Do_Dump(WindowPtr w, EventRecord *event)
  231. {
  232. Rect    tempRect;
  233. GrafPtr    savePort;
  234. ControlHandle    control;
  235. Point    mouse;
  236. unsigned long    clickAddr;
  237. short    part, offset, popItem;
  238.  
  239. mouse = event->where;        /* get the click position */
  240. GlobalToLocal(&mouse);
  241. /* see if we are in the dump area; if so, we won’t check the controls */
  242. tempRect = w->portRect;
  243. tempRect.right -= kScrollbarAdjust;
  244. if (PtInRect(mouse, &tempRect)) {
  245.     /* handle editing click */
  246.     if ((offset = mouse.h - dumpCWidMax * 6 - kDIST_FROMLEFT) >= 0)
  247.         if ((offset /= dumpCWidMax) % 5 != 4) {
  248.             tempRect.top = (mouse.v /= dumpLineHeight) * dumpLineHeight;
  249.             tempRect.left = ((offset /= 5) * 5) * dumpCWidMax + dumpCWidMax * 6 + kDIST_FROMLEFT;
  250.             tempRect.bottom = tempRect.top + dumpLineHeight;
  251.             tempRect.right = tempRect.left + (dumpCWidMax << 2);
  252.             clickAddr = ((unsigned long)(GetControlValue(dumpVScroll) + mouse.v) << 4)
  253.                         + (offset <<= 1);
  254.             if (popItem = TrackDumpObject(&tempRect, *(unsigned short *)(gMMemory + clickAddr))) {
  255.                 if (popItem == kD_Disasm) {
  256.                     ScrollDisasmTo(clickAddr >> 2);
  257.                     DoMenuWindows(kMItem_Disasm);
  258.                     }
  259.                 else if (event->modifiers & optionKey || popItem == kD_DisasmFrom) {
  260.                     ScrollDisasmTo(*(unsigned short *)(gMMemory + clickAddr) >> 1);
  261.                     DoMenuWindows(kMItem_Disasm);
  262.                     }
  263.                 else if (event->modifiers & cmdKey || popItem == kD_DumpFrom) {
  264.                     ScrollDumpTo(*(unsigned short *)(gMMemory + clickAddr) >> 3);
  265.                     }
  266.                 else {
  267.                     if (DoEditDump((short *)(gMMemory + clickAddr), clickAddr >> 1)) {
  268.                         InvalDump();
  269.                         InvalDisasm();
  270.                         }
  271.                     UnloadSeg(DoEditDump);
  272.                     }
  273.                 }
  274.             }
  275.     }
  276. else {
  277.     part = FindControl(mouse, w, &control);
  278.     switch ( part ) {
  279.         case 0:        /* do nothing for viewRect case */
  280.             break;
  281.         case kControlIndicatorPart:
  282.             if (gPrefs.NeXTScroll)
  283.                 (void)TrackThumb(control, mouse, RealTimeActionProc);
  284.             else {
  285.                 GetPort(&savePort);
  286.                 curPosW = GetNewWindow(kWIND_CurPos, nil, (WindowPtr)-1L);
  287.                 SetPortWindowPort(curPosW);
  288.                 TextMode(srcCopy);
  289.                 TextFont(monaco);
  290.                 TextSize(9);
  291.                 SetPort(savePort);
  292. // Apple would like us not to use GhostWindow, but in this case we avoid
  293. // plenty of useless activate/deactivate events, so we don’t feel guilty.
  294.  
  295.                 savePort = (GrafPtr)LMGetGhostWindow();
  296.                 LMSetGhostWindow(curPosW);
  297.                 ShowWindow(curPosW);
  298.                 (void) TrackThumb(control, mouse, NoRealTimeActionProc);
  299.                 DisposeWindow(curPosW);
  300.                 LMSetGhostWindow(savePort);
  301.                 InvalDump();
  302.                 }
  303.             break;
  304.         default:    /* clicked in an arrow, so track & scroll */
  305.             {
  306.             ControlActionUPP DumpActionProcUPP = NewControlActionProc(DumpActionProc);
  307.  
  308.             (void) TrackControl(control, mouse, DumpActionProcUPP);
  309.             if (DumpActionProcUPP)
  310.                 DisposeRoutineDescriptor(DumpActionProcUPP);
  311.             }
  312.             break;
  313.         }
  314.     }
  315. }
  316.  
  317. /* NoRealTimeActionProc: only updates the number in the little window up there */
  318.  
  319. static void NoRealTimeActionProc(ControlHandle , short value)
  320. {
  321. Str15    tempS;
  322. GrafPtr    savePort;
  323.  
  324. ShortToHexString(value << 3, tempS);
  325. GetPort(&savePort);
  326. SetPort(curPosW);
  327. MoveTo(kDIST_FROMLEFT,12);
  328. DrawString(tempS);
  329. SetPort(savePort);
  330. }
  331.  
  332. /* RealTimeActionProc: updates all of the window contents while dragging the scroll box */
  333.  
  334. static void RealTimeActionProc(ControlHandle control, short )
  335. {
  336. DrawDump((*control)->contrlOwner);
  337. }
  338.  
  339. static pascal void DumpActionProc(ControlHandle control, short part)
  340. {
  341. Rect    tempRect;
  342. WindowPtr    w;
  343. Ptr    addr;
  344. short    amount, oldAmount, newAmount, vc;
  345. Boolean    doScrollRect = false;
  346.  
  347. if ( part ) {        /* if it was actually in the control */
  348.     w = (*control)->contrlOwner;
  349.     switch ( part ) {
  350.         case kControlUpButtonPart:
  351.             amount = -1;
  352.             doScrollRect = true;
  353.             break;
  354.         case kControlDownButtonPart:
  355.             amount = 1;
  356.             doScrollRect = true;
  357.             break;
  358.         case kControlPageUpPart:
  359.             amount = (PRCT_T(w) - PRCT_B(w)) / dumpLineHeight + 1;
  360.             break;
  361.         case kControlPageDownPart:
  362.             amount = (PRCT_B(w) - PRCT_T(w)) / dumpLineHeight - 1;
  363.             break;
  364.         }
  365.     SetControlValue(control, (oldAmount = GetControlValue(control)) + amount);
  366.     if (doScrollRect && (newAmount = oldAmount - GetControlValue(control))) {
  367.         tempRect = w->portRect;
  368.         tempRect.right -= kScrollbarAdjust;
  369.         VScrollRect(&tempRect, newAmount * dumpLineHeight);
  370.         addr = &gMMemory[(unsigned long)GetControlValue(control) << 4];
  371.         vc = dumpFromTop;
  372.         if (newAmount < 0) {
  373.             vc += PRCT_B(w) - PRCT_T(w) - dumpLineHeight;
  374.             addr += ((PRCT_B(w) - PRCT_T(w)) / dumpLineHeight - 1) << 4;
  375.             }
  376.         MoveTo(PRCT_L(w) + kDIST_FROMLEFT, vc);
  377.         DrawLine(addr);
  378.         }
  379.     else
  380.         DrawDump(w);
  381.     }
  382. } /* DumpActionProc */
  383.  
  384. void DrawDump(WindowPtr w)
  385. {
  386. Rect    tempRect;
  387. GrafPtr    savePort;
  388. Point    tempPoint;
  389. Ptr    addr;
  390. short    j;
  391.  
  392. GetPort(&savePort);
  393. SetPort(w);
  394. tempRect = w->portRect;
  395. tempRect.bottom += dumpLineHeight;
  396. addr = &gMMemory[(unsigned long)GetControlValue(dumpVScroll) << 4];
  397. for(tempPoint.h = kDIST_FROMLEFT, j = dumpFromTop;
  398.     tempPoint.v = j, PtInRect(tempPoint, &tempRect);
  399.     j += dumpLineHeight, addr += 16) {
  400.  
  401.     MoveTo(PRCT_L(w) + kDIST_FROMLEFT, j);
  402.     DrawLine(addr);
  403.     }
  404. SetPort(savePort);
  405. }
  406.  
  407. /* DrawLine: draws a "line" of memory in the Dump window */
  408.  
  409. static void DrawLine(Ptr start)
  410. {
  411. Str63    tempS;
  412. short *hexPtr, *endPtr;
  413. Ptr    textPtr;
  414.  
  415. endPtr = (short *)(start + 16);
  416. textPtr = ShortToHexText(PTR2MEMWORD(start), (Ptr)&tempS);
  417. *textPtr++ = ':';
  418. for (hexPtr = (short *)start; hexPtr < endPtr; ) {
  419.     *textPtr++ = ' ';
  420.     textPtr = ShortToHexText(*hexPtr++, textPtr);
  421.     }
  422. DrawText(&tempS, 0, 45);
  423. }
  424.  
  425. /* SetupDumpCtlMax: sets up the CtlMax value of our scroll bar */
  426.  
  427. void SetupDumpCtlMax(ControlHandle theControl)
  428. {
  429. enum {
  430. kAdjustForPleasantGrow = 3
  431. };
  432.  
  433. WindowPtr    wind;
  434. short    newmax;
  435.  
  436. wind = (*theControl)->contrlOwner;
  437. newmax = 8191 - (PRCT_B(wind) - PRCT_T(wind) - kAdjustForPleasantGrow) / dumpLineHeight;
  438. if (newmax != GetControlMaximum(theControl)) {
  439.     SetControlMaximum(theControl, newmax);
  440.     InvalDump();
  441.     }
  442. }
  443.  
  444. void InvalDump(void)
  445. {
  446. Rect    tempRect;
  447. GrafPtr    savePort;
  448.  
  449. GetPort(&savePort);
  450. SetPort(gWPtr_Dump);
  451. tempRect = gWPtr_Dump->portRect;
  452. tempRect.right -= kScrollbarWidth;
  453. InvalRect(&tempRect);
  454. SetPort(savePort);
  455. }
  456.  
  457. /* TrackDumpObject: like all the TrackThing in the Mac OS, plus the popUp */
  458.  
  459. short    TrackDumpObject(RectPtr    r, short theLocation)
  460. {
  461. enum {
  462. kSimpleClick = -1,
  463. kDelay = 1 * 60 // one second
  464. };
  465.  
  466. Str32    itemStr;
  467. Str15    numStr;
  468. Point    myPt;
  469. MenuRef    tempMenu;
  470. long        timeout = TickCount();
  471. long        chosen = kSimpleClick;
  472. Boolean    inrect;
  473.  
  474. InvertRect(r);
  475. inrect = true;
  476. do {
  477.     Boolean tempB;
  478.  
  479.     GetMouse(&myPt);
  480.     if ((tempB = PtInRect(myPt, r)) != inrect) {
  481.         InvertRect(r);
  482.         inrect = tempB;
  483.         }
  484.     if (inrect == false)
  485.         timeout = TickCount();
  486.     if ((TickCount() - timeout) > GetDblTime()) {
  487.         tempMenu = gPopMenu;
  488.         if (noErr == HandToHand((Handle *)&tempMenu)) {
  489.             GetMenuItemText(tempMenu, kD_DisasmFrom, itemStr);
  490.             ShortToHexString(theLocation, numStr);
  491.             PLstrcat(itemStr, numStr);
  492.             SetMenuItemText(tempMenu, kD_DisasmFrom, itemStr);
  493.             GetMenuItemText(tempMenu, kD_DumpFrom, itemStr);
  494.             PLstrcat(itemStr, numStr);
  495.             SetMenuItemText(tempMenu, kD_DumpFrom, itemStr);
  496.             InsertMenu(tempMenu, hierMenu);
  497.             LocalToGlobal(&myPt);
  498.             chosen = PopUpMenuSelect(tempMenu, myPt.v, myPt.h, kD_Edit);
  499.             DeleteMenu(kRes_Menu_PopDump);
  500.             DisposeMenu(tempMenu);
  501.             }
  502.         }
  503.     }
  504. while( StillDown() );
  505. if (inrect)
  506.     InvertRect(r);
  507. if (chosen == kSimpleClick)
  508.     chosen = inrect ? toMenu(kRes_Menu_PopDump, kD_Edit) : 0L;
  509. return HiWrd(chosen) ? LoWrd(chosen) : 0;
  510. }
  511.  
  512. /* procedure called when closing the Dump window */
  513.  
  514. void CloseDump(WindowPtr w)
  515. {
  516. DoCloseWindow(w, kMItem_Dump);
  517. }
  518.  
  519. void RecalcDump(DialogRef w, RgnBalloonCursPtr theObj)
  520. {
  521. Rect    tempRect;
  522.  
  523. tempRect = w->portRect;
  524. tempRect.right -= kScrollbarWidth;
  525. RectRgn(theObj->zoneLocal, &tempRect);
  526. }
  527.  
  528. void getDragRectDump(WindowPtr w, RectPtr r)
  529. {
  530. *r = w->portRect;
  531. r->right -= kScrollbarAdjust;
  532. }
  533.  
  534. #endif
  535.  
  536.